// function id<Type>(value: Type): Type {
//   // Property 'length' does not exist on type 'Type'.
//   // value 的类型是泛型，所以很有可能传来的数据类型没有 length
//   console.log(value.length)
//   return value
// }

// /* let str = '88'
// const r = id(str) */

// const arr = ['8', '9']
// const r = id(arr)

// 如何解决上面的报错呢？

// 方法1：通过 typeof 进行类型收窄
/* function id<Type>(value: Type): Type {
  if (typeof value === 'string' || Array.isArray(value)) {
    console.log(value.length)
  }
  return value
} */

// 方法2：通过 as 断言进行类型收窄
/* function id<Type>(value: Type): Type {
  // console.log((value as string).length)
  // console.log((value as string[]).length)
  let r = value as string[]
  console.log(r.length)
  return value
} */

// 方法3，推荐
// T 要满足（extends）具有 length 属性，并且值是 number
// 以后传递过来的泛型实参要满足具有 length 属性

/* interface ILength {
  length: number
}
// function id<T extends { length: number }>(value: T): T {
function id<T extends ILength>(value: T): T {
  console.log(value.length)
  return value
} */

// id<string>('abc')
// id<string[]>(['a', 'b', 'c'])
// id<{ length: number }>({ length: 8 })

// 方法4，可以指定更加具体的类型
// 传递过来的泛型参数是 T
// 函数参数要是 T 组成的数组
function id<T>(value: T[]): T[] {
  console.log(value.length)
  return value
}

id<string>(['a', 'b'])

// id('abc') 有局限，会报错
export {}
